package com.sanq.product.cab.redis.impl.single;

import com.sanq.product.cab.redis.RedisLock;
import com.sanq.product.cab.tools.date.LocalDateUtils;
import com.sanq.product.cab.tools.log.LogUtil;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.Resource;
import java.util.Collections;

import static com.sanq.product.cab.redis.JedisPoolService.*;

/**
 * com.sanq.product.cab.redis.impl.single.IRedisSingleLock
 *
 * @author sanq.Yan
 * @date 2020/2/20
 */
@Service("lock")
public class RedisSingleLock extends RedisLock {

    @Resource
    private JedisPool jedisPool;

    @Override
    public void lock(String key, String value) {
        while (true) {
            try (Jedis jedis = jedisPool.getResource()) {
                if (SET_OK.equals(jedis.setex(key, DEFAULT_SECOND, value))) {
                    LogUtil.getInstance(getClass()).i("线程ID：{}加锁成功， 时间：{}", Thread.currentThread().getId(), LocalDateUtils.nowTime());

                    isOpenExpirationRenewal = true;
                    scheduleExpirationRenewal(jedis, key, value);

                    break;
                }

                LogUtil.getInstance(getClass()).i("线程ID：{}获取锁失败，休眠10秒! 时间：{}", Thread.currentThread().getId(), LocalDateUtils.nowTime());

                sleepBySecond(10);
            }
        }
    }

    @Override
    public void unLock(String key, String value) {
        try (Jedis jedis = jedisPool.getResource()) {
            LogUtil.getInstance(getClass()).i("线程ID：{} 解锁， 时间：{}", Thread.currentThread().getId(), LocalDateUtils.nowTime());

            String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
            jedis.eval(script, Collections.singletonList(key), Collections.singletonList(value));
            isOpenExpirationRenewal = false;
        }
    }

}
